/*
   Copyright (c) [2021] IT.SOS
   wxsdk is licensed under Mulan PSL v2.
   You can use this software according to the terms and conditions of the Mulan PSL v2.
   You may obtain a copy of Mulan PSL v2 at:
            http://license.coscl.org.cn/MulanPSL2
   THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
   See the Mulan PSL v2 for more details.
*/

package wxchat

import (
	"encoding/json"
	"gitee.com/itsos/wxsdk/common/config"
	"strings"
	"sync"
)

type accessTokenDTO struct {
	AccessToken string `json:"access_token"`
	ExpiresIn   int    `json:"expires_in"`
}

// AccessToken 全局token
type AccessToken interface {
	getAccessToken() string
	getKey() string
	getLockKey() string
}

type accessToken struct{}

func (a accessToken) getKey() string {
	return "access_token:" + config.Cfg.GetWxAppId()
}

func (a accessToken) getLockKey() string {
	return "access_token_lock:" + config.Cfg.GetWxAppId()
}

func (a accessToken) getAccessToken() string {
	var http = newHttp()

	// 7200 - 200
	http.setExpire(7000)
	http.setKey(a.getKey())
	http.setLockKey(a.getLockKey())

	resp := http.get(strings.NewReplacer("{appid}", config.Cfg.GetWxAppId(),
		"{secret}", config.Cfg.GetWxAppSecret()).Replace(getAccessToken))
	dto := &accessTokenDTO{}
	if err := json.Unmarshal(resp, dto); err != nil {
		panic(err)
	}
	return dto.AccessToken
}

var _ AccessToken = (*accessToken)(nil)

var instAccessToken AccessToken
var onceAccessToken sync.Once

func NewAccessToken() AccessToken {
	onceAccessToken.Do(func() {
		instAccessToken = new(accessToken)
	})
	return instAccessToken
}
